#include "tcpServer.h"

/**
 * @brief Construct a new Tcp Server:: Tcp Server object
 * 
 */
TcpServer::TcpServer()
{

}

/**
 * @brief Destroy the Tcp Server:: Tcp Server object
 * 
 */
TcpServer::~TcpServer()
{
    stop();
}

/**
 * @brief 初始化赋值
 * 
 * @param ip 
 * @param port 
 */
void TcpServer::init(const string& ip,const int &port)
{
    ip_ = ip;
    port_ = port;
}

bool TcpServer::start()
{
    stop();

    tcpServer_ = new QTcpServer(this);
    if(tcpServer_->listen(QHostAddress::Any,port_))
    {
        LOG(INFO)<<"tcpServer listen success!";
        QVariantMap stateMap;
        stateMap["type"] = "tcpServer";
        stateMap["state"] = true;
        emit signal_openStatus(stateMap);
    }
    else
    {
        LOG(INFO)<<"tcpServer listen fail!";
        QVariantMap stateMap;
        stateMap["type"] = "tcpServer";
        stateMap["state"] = false;
        emit signal_openStatus(stateMap);
        return false;
    }

    //当有客户端连接时
    sSocket_ = new QTcpSocket(this);
    connect(tcpServer_,&QTcpServer::newConnection,this,[=]{
        sSocket_ = tcpServer_->nextPendingConnection();
        connect(sSocket_,&QTcpSocket::readyRead,this,&TcpServer::slot_read);
    });

    //客户端断开连接时
    connect(sSocket_,&QTcpSocket::disconnected,this,[=]{
            stop();
    });

    return true;
}

/**
 * @brief 外部通过槽开启
 * 
 */
void TcpServer::slot_start()
{
    start();
}

/**
 * @brief 关闭服务器
 * 
 */
void TcpServer::stop()
{
    if(sSocket_ != nullptr)
    {
        sSocket_->close();
        sSocket_->disconnect();
        delete sSocket_;
        sSocket_ = nullptr;
    }

    if(tcpServer_ != nullptr)
    {
        tcpServer_->close();
        tcpServer_->disconnect();
        delete tcpServer_;
        tcpServer_ = nullptr;
    }
}

/**
 * @brief 服务器数据发送
 * 
 * @param msg 
 */
void TcpServer::write(const QByteArray& msg)
{
    if(tcpServer_!=nullptr && sSocket_ != nullptr &&
        sSocket_->state() == QAbstractSocket::ConnectedState)
        {
            sSocket_->write(msg);
        }
}

/**
 * @brief 外部接口 要通过服务器发送的数据
 * 
 * @param msg 
 */
void TcpServer::slot_write(const QString& msg)
{
    LOG(INFO)<<"TX msg: "<<msg.toUtf8().toStdString();
    QByteArray data = msg.toUtf8();
    write(data);
}

/**
 * @brief 服务器接受数据的槽函数
 * 
 */
void TcpServer::slot_read()
{
    rec_buffer_.clear();
    rec_buffer_ = sSocket_->readAll();
    LOG(INFO)<<"RX msg:"<<QString::fromUtf8(rec_buffer_).toStdString();
    QVariantMap data;
    data["type"] = "tcpServer";
    data["data"] = rec_buffer_;
    emit signal_tcpServer(data);
}